package com.eduagent.xwqeduagent.api.characterRecognition.HandwrittenTextRecognition;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import com.eduagent.xwqeduagent.api.characterRecognition.HandwrittenTextRecognition.demo.FileUtil;
import com.eduagent.xwqeduagent.api.characterRecognition.HandwrittenTextRecognition.demo.HttpUtil;

/**
 * 手写文字识别API接口实现
 * 接口文档: https://doc.xfyun.cn/rest_api/手写文字识别.html
 */
public class HandwrittenTextRecognitionAPI {
    // 手写文字识别webapi接口地址
    private static final String WEBOCR_URL = "https://webapi.xfyun.cn/v1/service/v1/ocr/handwriting";
    
    // 应用APPID
    private String appId;
    
    // 接口密钥
    private String apiKey;
    
    /**
     * 构造函数
     * @param appId 讯飞开放平台应用ID
     * @param apiKey 接口密钥
     */
    public HandwrittenTextRecognitionAPI(String appId, String apiKey) {
        this.appId = appId;
        this.apiKey = apiKey;
    }
    
    /**
     * 组装http请求头
     * @param language 语言，可选值：en（英文），cn|en（中文或中英混合）
     * @param location 是否返回文本位置信息，可选值：false（否），true（是），默认为false
     * @return 请求头Map
     * @throws UnsupportedEncodingException
     */
    private Map<String, String> constructHeader(String language, String location) throws UnsupportedEncodingException {
        // 系统当前时间戳
        String xCurTime = System.currentTimeMillis() / 1000L + "";
        System.out.println("当前时间戳: " + xCurTime);
        
        // 业务参数
        String param = "{\"language\":\"" + language + "\",\"location\":\"" + location + "\"}";
        System.out.println("业务参数: " + param);
        
        String xParam = new String(Base64.encodeBase64(param.getBytes("UTF-8")));
        System.out.println("Base64编码后的参数: " + xParam);
        
        // 生成令牌
        String xCheckSum = DigestUtils.md5Hex(apiKey + xCurTime + xParam);
        System.out.println("生成的CheckSum: " + xCheckSum);
        
        // 组装请求头
        Map<String, String> header = new HashMap<String, String>();
        header.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
        header.put("X-Param", xParam);
        header.put("X-CurTime", xCurTime);
        header.put("X-CheckSum", xCheckSum);
        header.put("X-Appid", appId);
        
        System.out.println("请求头信息:");
        for (Map.Entry<String, String> entry : header.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        
        return header;
    }
    
    /**
     * 通过本地图片文件路径识别手写文字
     * @param imagePath 图片文件路径
     * @param language 语言，可选值：en（英文），cn|en（中文或中英混合）
     * @param location 是否返回文本位置信息，可选值：false（否），true（是），默认为false
     * @return 识别结果JSON字符串
     * @throws IOException
     */
    public String recognizeFromFile(String imagePath, String language, String location) throws IOException {
        // 检查文件是否存在
        File imageFile = new File(imagePath);
        if (!imageFile.exists()) {
            System.err.println("图片文件不存在: " + imagePath);
            return "{\"code\":\"-1\",\"desc\":\"图片文件不存在: " + imagePath + "\",\"data\":\"\",\"sid\":\"\"}";
        }
        
        if (!imageFile.isFile()) {
            System.err.println("指定路径不是一个文件: " + imagePath);
            return "{\"code\":\"-1\",\"desc\":\"指定路径不是一个文件: " + imagePath + "\",\"data\":\"\",\"sid\":\"\"}";
        }
        
        // 检查文件大小
        long fileSize = imageFile.length();
        System.out.println("图片文件大小: " + fileSize + " bytes");
        if (fileSize > 4 * 1024 * 1024) {
            System.err.println("图片文件过大，超过4M限制");
            return "{\"code\":\"-1\",\"desc\":\"图片文件过大，超过4M限制\",\"data\":\"\",\"sid\":\"\"}";
        }
        
        // 读取图像文件，转二进制数组，然后Base64编码
        System.out.println("开始读取图片文件: " + imagePath);
        byte[] imageByteArray = FileUtil.read2ByteArray(imagePath);
        System.out.println("图片读取完成，大小: " + imageByteArray.length + " bytes");
        
        return recognizeFromByteArray(imageByteArray, language, location);
    }
    
    /**
     * 通过图片二进制数据识别手写文字
     * @param imageByteArray 图片二进制数据
     * @param language 语言，可选值：en（英文），cn|en（中文或中英混合）
     * @param location 是否返回文本位置信息，可选值：false（否），true（是），默认为false
     * @return 识别结果JSON字符串
     * @throws IOException
     */
    public String recognizeFromByteArray(byte[] imageByteArray, String language, String location) throws IOException {
        try {
            // 检查参数
            if (imageByteArray == null || imageByteArray.length == 0) {
                System.err.println("图片数据为空");
                return "{\"code\":\"-1\",\"desc\":\"图片数据为空\",\"data\":\"\",\"sid\":\"\"}";
            }
            
            // 检查图片大小
            if (imageByteArray.length > 4 * 1024 * 1024) {
                System.err.println("图片数据过大，超过4M限制");
                return "{\"code\":\"-1\",\"desc\":\"图片数据过大，超过4M限制\",\"data\":\"\",\"sid\":\"\"}";
            }
            
            // 构造请求头
            Map<String, String> header = constructHeader(language, location);
            
            // Base64编码图片数据
            String imageBase64 = new String(Base64.encodeBase64(imageByteArray), "UTF-8");
            System.out.println("图片Base64编码后大小: " + imageBase64.length() + " 字符");
            
            // 进行URL编码
            String encodedImageBase64 = URLEncoder.encode(imageBase64, "UTF-8");
            System.out.println("图片URLEncode编码后大小: " + encodedImageBase64.length() + " 字符");
            
            // 构造请求体
            String bodyParam = "image=" + encodedImageBase64;
            System.out.println("开始发送请求到: " + WEBOCR_URL);
            
            // 发送POST请求
            String response = HttpUtil.doPost(WEBOCR_URL, header, bodyParam);
            System.out.println("接收到响应，响应长度: " + (response != null ? response.length() : 0));
            
            return response;
        } catch (Exception e) {
            System.err.println("识别手写文字失败: " + e.getMessage());
            e.printStackTrace();
            return "{\"code\":\"-1\",\"desc\":\"识别手写文字失败: " + e.getMessage() + "\",\"data\":\"\",\"sid\":\"\"}";
        }
    }
    
    /**
     * 通过Base64编码后的图片数据识别手写文字
     * @param imageBase64 Base64编码后的图片数据
     * @param language 语言，可选值：en（英文），cn|en（中文或中英混合）
     * @param location 是否返回文本位置信息，可选值：false（否），true（是），默认为false
     * @return 识别结果JSON字符串
     * @throws IOException
     */
    public String recognizeFromBase64(String imageBase64, String language, String location) throws IOException {
        try {
            // 检查参数
            if (imageBase64 == null || imageBase64.isEmpty()) {
                System.err.println("Base64图片数据为空");
                return "{\"code\":\"-1\",\"desc\":\"Base64图片数据为空\",\"data\":\"\",\"sid\":\"\"}";
            }
            
            // 检查图片大小
            if (imageBase64.length() > 4 * 1024 * 1024) {
                System.err.println("Base64图片数据过大，超过4M限制");
                return "{\"code\":\"-1\",\"desc\":\"Base64图片数据过大，超过4M限制\",\"data\":\"\",\"sid\":\"\"}";
            }
            
            // 构造请求头
            Map<String, String> header = constructHeader(language, location);
            
            // 进行URL编码
            String encodedImageBase64 = URLEncoder.encode(imageBase64, "UTF-8");
            System.out.println("图片URLEncode编码后大小: " + encodedImageBase64.length() + " 字符");
            
            // 构造请求体
            String bodyParam = "image=" + encodedImageBase64;
            System.out.println("开始发送请求到: " + WEBOCR_URL);
            
            // 发送POST请求
            String response = HttpUtil.doPost(WEBOCR_URL, header, bodyParam);
            System.out.println("接收到响应，响应长度: " + (response != null ? response.length() : 0));
            
            return response;
        } catch (Exception e) {
            System.err.println("识别手写文字失败: " + e.getMessage());
            e.printStackTrace();
            return "{\"code\":\"-1\",\"desc\":\"识别手写文字失败: " + e.getMessage() + "\",\"data\":\"\",\"sid\":\"\"}";
        }
    }
} 